import { t } from 'i18next'
import { DepartmentEntity, TemplateEntity, UserInDeptEntity } from '@/api/addMt/interface'
import { InitOption, MccCurrentMt } from '../interface'
import { CONSTANT } from '../utils/utils'
import { SelectedMt } from './selected'

export interface TemplateFetchRes {
	success: 0 | 1
	total: number
	list: TemplateEntity[]
}
export interface NodeEntity {
	name: string
	type: 'group' | 'org' | 'monitor' | 'template'
}
export class DepartmentUser {
	name: string
	e164: string
	ip: string
	email: string
	moid: string
	portrait: string
	mobilePhone: string
	workPhone: string
	protocol: 0 | 1 | 2 | 255
	dept: { departmentName: string }
	constructor(user: UserInDeptEntity) {
		this.name = user.name
		this.moid = user.moid
		this.portrait = user.portrait32
		this.email = user.email || ''
		this.mobilePhone = user.mobile_phone
		this.workPhone = user.work_phone || ''
		this.protocol = user.protocol != null ? user.protocol : CONSTANT.callType.AUTO
		this.ip = isIpInPending(user.account) ? user.account : ''
		this.e164 = user.e164 || ''
		this.dept = {
			departmentName: user.depts && user.depts[0] ? user.depts[0].department_name : '',
		}
	}
}
export class Template {
	name: string
	e164: string
	meetingType: 0 | 1 | 2
	constructor(template: TemplateEntity) {
		this.name = template.name
		this.e164 = template.e164 || template.preAssignedMeetingNumber || ''
		this.meetingType = template.conf_type || template.meetingType || 0
	}
}
export class TreeNode {
	name: string
	/**group：公共群组，org：组织架构 ,monitor:网络监控, template: 模板 */
	type: 'group' | 'org' | 'monitor' | 'template'
	constructor(node: NodeEntity) {
		this.name = node.name
		this.type = node.type
	}
}
export type PendingMt = TreeNode | DepartmentUser | Template
export interface PendingMtModel<T extends PendingMt> {
	item: T
	status: {
		isParent: boolean //是否枝干节点
		clickTimestamp: number | null //选中点击时间戳
		isSelected: boolean //是否选中
		isOpen: boolean //是否展开
		isOpenMoreOpt: boolean //更多展开
		isAdded: boolean //添加到右侧
		isInMcc: boolean //是否在会控中的当前cascade里
	}
	attr: {
		fromSearchVal: string //为了搜索手机等，再添加到右侧改变默认的下参方式
	}
	nestingLevel: number
	id: string
	pid: string
	children: PendingMtModel<TreeNode>[]
	users: PendingMtModel<DepartmentUser | Template>[]
}

export type PendingItem<T extends PendingMt = PendingMt> = Omit<PendingMtModel<T>, 'users'>

export const pendingModelTranslator = <T extends PendingMt>(item: T): PendingMtModel<T> => {
	const isParent = item instanceof TreeNode
	return {
		item,
		status: {
			isParent,
			isAdded: false,
			isSelected: false,
			clickTimestamp: null,
			isOpen: false,
			isOpenMoreOpt: false,
			isInMcc: false,
		},
		attr: {
			fromSearchVal: '',
		},
		nestingLevel: 0,
		id: '',
		pid: '',
		children: [],
		users: [],
	}
}

export function pendingDepartmentTranslator(
	departmentTree: DepartmentEntity[],
	initial: { isOpen?: boolean; fromSearchVal?: string } = { isOpen: false, fromSearchVal: '' }
) {
	let stack: DepartmentEntity[] = [...departmentTree]
	let ids: string[] = departmentTree.map((x) => x.id)
	let nodeMap: { [key: string]: PendingMtModel<TreeNode> } = {}
	while (stack.length > 0) {
		const item = stack.shift()!
		//pid处理, 部门多个 _ 的兼容
		if (item.pid) {
			if (item.pid.endsWith('_')) {
				item.pid = item.pid.slice(0, -1)
			}
		}
		let node = pendingModelTranslator(new TreeNode({ name: item.name, type: item.type === '1' ? 'group' : 'org' }))
		node.id = item.id
		node.pid = item.pid
		node.users = item.users.map((x) => {
			let userNode = pendingModelTranslator(new DepartmentUser(x))
			userNode.id = item.id + '$$' + userNode.item.moid
			userNode.pid = item.id
			userNode.attr.fromSearchVal = initial.fromSearchVal ?? ''
			if (nodeMap[node.pid]) {
				userNode.nestingLevel = nodeMap[node.pid].nestingLevel + 2
			} else {
				userNode.nestingLevel = 1
			}
			return userNode
		})
		node.status.isOpen = !!initial.isOpen // 是否全部展开树节点
		node.attr.fromSearchVal = initial.fromSearchVal ?? ''
		if (nodeMap[node.pid]) {
			node.nestingLevel = nodeMap[node.pid].nestingLevel + 1
			nodeMap[node.pid].children.push(node)
		}
		nodeMap[node.id] = node
		if (item.children && item.children.length > 0) {
			for (let i = item.children.length - 1; i >= 0; i--) {
				stack.unshift(item.children[i])
			}
		}
	}
	return ids.map((id) => nodeMap[id])
}
export function pendingTemplateListTranslator(templates: TemplateEntity[]) {
	return templates
		.filter((i) => !i.smart_cascade_mode) //过滤智能级联会议模板
		.map((x) => {
			let node = pendingModelTranslator(new Template(x))
			node.nestingLevel = 1
			node.pid = CONSTANT.pendingRootId.template
			node.id = `template$$${node.item.e164}`
			return node
		})
}
export function pendingMonitorTranslator() {
	let node = pendingModelTranslator(new TreeNode({ name: t('网络监控'), type: 'monitor' }))
	node.id = CONSTANT.pendingRootId.monitor
	return node
}
export function pendingTemplateTranslator(initial?: { isOpen: boolean }) {
	let node = pendingModelTranslator(new TreeNode({ name: t('会议模板'), type: 'template' }))
	node.id = CONSTANT.pendingRootId.template
	node.status.isOpen = initial ? initial.isOpen : false // 是否展开树节点
	return node
}
export interface SearchResult {
	departments: DepartmentEntity[]
	templates: TemplateEntity[]
	user_size_data: {
		template: number
		[key: string]: number
	}
}
export function pendingTotalNumTranslator(
	{ departments = [], user_size_data }: SearchResult,
	showTrees: InitOption['showTrees']
) {
	//计算全部数量
	let totalNum = 0
	const ids = departments.map((x: any) => x.id)
	for (let key in user_size_data) {
		if (
			(showTrees.includes('org') && ids.includes(key)) ||
			(showTrees.includes('template') && key === 'template')
		) {
			totalNum += ~~user_size_data[key]
		}
	}
	return totalNum
}
export function pendingSearchTreeTranslator(
	{ departments = [], templates = [], user_size_data }: SearchResult,
	fromSearchVal: string,
	showTrees: InitOption['showTrees']
) {
	//拼接最终结构
	let tree: PendingMtModel<TreeNode>[] = []
	if (showTrees.includes('org') && departments.length > 0) {
		const departmentModel = pendingDepartmentTranslator(departments, { isOpen: true, fromSearchVal }) //搜索需要默认展开节点，并且添加到右侧判断需要搜索值共同判断
		departmentModel.forEach((x) => (x.item.name = `${x.item.name}(${user_size_data[x.id]})`)) //顶级，名称需增加上数量
		tree = [...tree, ...departmentModel]
	}
	if (showTrees.includes('template') && templates.length > 0) {
		const templateModel = pendingTemplateListTranslator(templates)
		let template = pendingTemplateTranslator()
		template.item.name = `${template.item.name}(${user_size_data['template']})`
		template.users = templateModel
		template.status.isOpen = true
		tree = [...tree, template]
	}
	return tree
}
//////////////其他工具函数////////////////
export const isIpInPending = (ip: string) => {
	if (ip && (CONSTANT.reg.regIP.test(ip) || CONSTANT.reg.e164Ip.test(ip))) {
		return true
	} else {
		return false
	}
}
export function isUser(item: PendingMt): item is DepartmentUser {
	return item instanceof DepartmentUser
}
export function isTreeNodePendingItem(data: PendingItem): data is PendingItem<TreeNode> {
	return data.item instanceof TreeNode
}
export function isNotTreeNodePendingItem(data: PendingItem): data is PendingItem<DepartmentUser | Template> {
	return !(data.item instanceof TreeNode)
}
export function isNotTreeNode(item: PendingMt): item is DepartmentUser | Template {
	return !(item instanceof TreeNode)
}
export function getItemInPending(
	tree: PendingMtModel<TreeNode>[],
	callback: (item: PendingMtModel<TreeNode>) => void | boolean | 'continue'
) {
	let stack = [...tree]
	while (stack.length > 0) {
		const item = stack.shift()!
		let needStop = callback(item)
		if (needStop === false) {
			break
		} else if (needStop === 'continue') {
			continue
		}
		if (item.children.length > 0) {
			for (let i = item.children.length - 1; i >= 0; i--) {
				stack.unshift(item.children[i])
			}
		}
	}
}
//树->平铺，并改变相关状态
export function flatList(tree: PendingMtModel<TreeNode>[], mccCurrentMts: MccCurrentMt[], selectedMts: SelectedMt[]) {
	let stack: PendingMtModel<PendingMt>[] = [...tree]
	let result: PendingItem[] = []
	while (stack.length !== 0) {
		const { item, children, users, status, id, pid, nestingLevel, attr } = stack.shift()!
		//比较处理，改变相关状态
		if (isNotTreeNode(item)) {
			status.isInMcc = false
			for (let i = 0; i < mccCurrentMts.length; i++) {
				const mccCurrentMt = mccCurrentMts[i]
				if (isSameMt(item, mccCurrentMt)) {
					status.isInMcc = true
					break
				}
			}
			status.isAdded = false
			for (let c = 0; c < selectedMts.length; c++) {
				const selectedMt = selectedMts[c]
				if (isSameMt(item, selectedMt)) {
					status.isAdded = true
					break
				}
			}
		}
		result.push({
			item,
			status,
			children,
			id,
			pid,
			nestingLevel,
			attr,
		})
		if (status.isParent && status.isOpen) {
			//将人员加入到循环平铺里
			let sub = [...users, ...children]
			for (let i = sub.length - 1; i >= 0; i--) {
				stack.unshift(sub[i])
			}
		}
	}
	return result
}
export function isSameMt(pendingMt: DepartmentUser | Template, compareMt: SelectedMt | MccCurrentMt): boolean {
	if (isUser(pendingMt)) {
		//通过 moid 判断
		if (pendingMt.moid === compareMt.moid) {
			return true
		}
		//另一种可能情况，moid判断
		if (compareMt.accountType === CONSTANT.accountType.softTerminal) {
			return pendingMt.moid === compareMt.account
		}
		//e164
		if (compareMt.accountType === CONSTANT.accountType.sat) {
			return pendingMt.e164 === compareMt.account
		}
		//ip
		if (
			compareMt.accountType === CONSTANT.accountType.IP ||
			compareMt.accountType === CONSTANT.accountType.e164Ip
		) {
			return pendingMt.ip === compareMt.account
		}
		//电话
		if (compareMt.accountType === CONSTANT.accountType.phone) {
			return pendingMt.mobilePhone === compareMt.account || pendingMt.workPhone === compareMt.account
		}
	} else {
		if (compareMt.accountType === CONSTANT.accountType.template) {
			if (pendingMt.e164 === compareMt.account) {
				return true
			}
		}
	}
	return false
}
